package cn.javacc.common.web;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * 
 * @author mzh2008@163.com 2012-11-13 下午10:28:43
 *
 */
public class JrHttpRequest extends HttpServletRequestWrapper {
    protected Log log = LogFactory.getLog(JrHttpRequest.class);
    private Hashtable<String, Object> params;

    @SuppressWarnings("unchecked")
    public JrHttpRequest(HttpServletRequest request) {
        super(request);
        params = new Hashtable<String, Object>();
        params.putAll(request.getParameterMap());
        String[] encstrs = this.getParameterValues("encstr");
        boolean isport = request.getRequestURI().startsWith(request.getContextPath() + "/port");
        if (encstrs != null) {
            // log.debug("开始处理加密串:" + encstr);
            params.remove("encstr");
            // 解密
            for (String encstr : encstrs) {
                String qstr = null;
                if (isport) {
                    qstr = EncUtils.decode(encstr);
                } else {
                    qstr = ParamEncHelper.decodeHex(encstr);
                }
                StringTokenizer st = new StringTokenizer(qstr, "&");
                while (st.hasMoreTokens()) {
                    String pairs = st.nextToken();
                    if (pairs.trim().equals(""))
                        continue;
                    if (pairs.indexOf('=') > 0) {
                        String key = pairs.substring(0, pairs.indexOf('='));
                        String value = pairs.substring(pairs.indexOf('=') + 1);
                        params.put(key, new String[] { value });
                    } else {
                        params.put(pairs, new String[] { "" });
                    }
                }
            }
        }

        // 解密post参数
        List<String> names = new ArrayList<String>();
        names.addAll(params.keySet());
        for (String name : names) {
            if (!name.endsWith(".enc"))
                continue;
            String[] vals = (String[]) params.get(name);
            if (vals == null)
                continue;
            for (int i = 0; i < vals.length; i++) {
                // log.debug("待解密:" + vals[i]);
                if (isport)
                    vals[i] = EncUtils.decode(vals[i]);
                else
                    vals[i] = ParamEncHelper.decodeHex(vals[i]);
            }
            params.put(name.substring(0, name.lastIndexOf(".")), vals);
            params.remove(name);
        }
        // log.debug("解密后的参数:" + params);
    }

    private String qstr = null;
    
    @Override
    public String getQueryString() {
        boolean isport = getRequestURI().startsWith(getContextPath() + "/port");
        if (qstr == null) {
            qstr = super.getQueryString();
            while (qstr != null && qstr.indexOf("encstr=") >= 0) {
                // 解密
                String fstr = qstr.substring(0, qstr.indexOf("encstr="));
                String lstr = qstr.substring(qstr.indexOf("encstr=") + "encstr=".length());
                String pstr = lstr.indexOf("&") >= 0 ? lstr.substring(0, lstr.indexOf("&")) : lstr;
                lstr = lstr.substring(pstr.length());
                // log.debug("解密前加密串：" + pstr);
                if (isport)
                    pstr = EncUtils.decode(pstr);
                else
                    pstr = ParamEncHelper.decodeHex(pstr);
                // log.debug("解密后的原串：" + pstr);
                qstr = fstr + pstr + lstr;
            }
            // log.debug("解密后参数串：" + qstr);
        }
        return qstr;
    }

    @Override
    public String getParameter(String name) {
        Object[] val = (Object[]) params.get(name);
        if (val == null || val.length <= 0)
            return null;
        return val[0] == null ? null : val[0].toString();
    }

    @SuppressWarnings("rawtypes")
	@Override
    public Map getParameterMap() {
        return params;
    }

    @Override
    public String[] getParameterValues(String name) {
        Object[] val = (Object[]) params.get(name);
        if (val == null)
            return null;
        String[] stres = new String[val.length];
        for (int i = 0; i < val.length; i++) {
            stres[i] = val[i] == null ? null : val[i].toString();
        }
        return stres;
    }

    @SuppressWarnings("rawtypes")
	@Override
    public Enumeration getParameterNames() {
        return params.keys();
    }
}
